function func(str1) {
    let arr = [];
    let arr_4 = [24, 16, 8, 0], flag = 0;
    let code_v, index, index2, v1, v2, num = 0, len = str1.length, v3, v4;
    for (let i = 0; i < len;) {
        if (flag === 0) {
            code_v = str1.charCodeAt(i);
            v2 = code_v;
            index = (i + num) >> 2;
            index2 = (i + num) & 3;
            if (code_v >= 2048) {
                v1 = code_v >> 12;
                v2 = v1 | 224;
                flag = 1;
            } else {
                i++;
            }
        } else if (flag === 1 || flag === 2) {
            if (flag === 1) {
                v1 = code_v >> 6;
                flag = 2;
                num++;
                index = (i + num) >> 2;
                index2 = (i + num) & 3;
            } else {
                v1 = code_v;
                flag = 0;
                num++;
                index = (i + num) >> 2;
                index2 = (i + num) & 3;
                i++;
            }
            v2 = v1 & 63;
            v2 |= 128;
        }

        if (arr[index] === undefined) {
            arr[index] = v2 << arr_4[index2];
        } else {
            arr[index] |= (v2 << arr_4[index2]);
        }
    }
    const new_arr_4 = [-2147483648, 8388608, 32768, 128];
    v1 = len + num;
    v2 = v1 % 64;
    v3 = arr.length;
    v3 = Math.floor(v3 / 16) * 16 + (v2 >> 2);
    if (arr[v3] === undefined)
        v4 = 0;
    else
        v4 = 1;
    for (let i = (v2 >> 2) + v4; i < 16; i++)
        arr.push(0);
    arr[v3] |= new_arr_4[v2 & 3];
    if (v2 < 56) {
        arr[arr.length - 1] = v1 << 3;
    }

    return arr;
}

function func2(arr) {
    let arr80, v;
    let obj = {
        h0: 1732584193,
        h1: 4023233417,
        h2: 2562383102,
        h3: 271733878,
        h4: 3285377520
    }
    for (let i = 0; i < arr.length / 16; i++) {
        arr80 = [];
        for (let j = 0; j < 16; j++)
            arr80.push(arr[16 * i + j]);
        for (let j = 16; j < 80; j++) {
            v = arr80[j - 3] ^ arr80[j - 8] ^ arr80[j - 14] ^ arr80[j - 16];
            arr80.push((v << 1) | (v >>> 31));
        }
        func3(arr80, obj);
    }
    return obj;
}

function func3(arr80, obj) {
    const arr13 = [
        null,
        1732584193,
        4023233417,
        2562383102,
        3285377520,
        false,
        true,
        2147483648,
        4294967295,
        4294967296,
        1518500249,
        1859775393,
        1894007588
    ]; // 固定数组
    let h0 = obj.h0, h1 = obj.h1, h2 = obj.h2, h3 = obj.h3, h4 = obj.h4;
    for (let i = 0; i < 80; i++) {
        var v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13;
        var v_1, v_2, v_3, v_4, v_5, v_6, v_7, v_8, v_9;
        var flag = 0;
        v1 = h0 << 5; // 55
        v2 = h0 >>> 27;//34,
        v3 = v1 | v2;//17
        v4 = h4 + v3;// 34
        v5 = arr80[i];// 17
        v6 = v4 + v5;// 55 8 55

        if (i < 20) {
            v7 = h1 & h2; //17
            v8 = ~h1;// 34
            v9 = v8 & h3;// 11
            v10 = v7 | v9;// 34
            v11 = arr13[10];// 11
            v12 = v10 + v11;// 17
            v13 = v12 + v6;// 55 8
        } else if (i >= 20 && i < 40) {
            v_1 = v6;  //11
            v_2 = h1 ^ h2;//55
            v_3 = v_2 ^ h3; // 17
            v_4 = arr13[11];// 55
            v_5 = v_3 + v_4;// 34
            v_6 = v_1 + v_5;// 11 8
            flag = 1;
        } else if (i >= 40 && i < 60) {
            v_1 = v6; // 11
            v_2 = h1 & h2; // 55
            v_3 = h1 & h3; // 34
            v_4 = v_2 | v_3; // 17
            v_5 = h2 & h3;// 34
            v_6 = v_4 | v_5; // 55
            v_7 = arr13[12];// 34
            v_8 = v_6 - v_7; //17
            v_9 = v_8 + v_1; // 11 8
            flag = 2;
        } else {
            v_1 = v6; // 34
            v_2 = h1 ^ h2; // 11
            v_3 = h3 ^ v_2; // 17
            v_4 = v_3 - 899497514; // 11
            v_5 = v_1 + v_4; // 34 8
            v_6 = arr13[10]; // 34
            flag = 3;
        }

        h4 = h3; // 97 存储 46 的值
        h3 = h2;// 46 存储 131 的值

        var v14, v15, v16;
        v14 = arr13[8];// 34
        v15 = h1 << 30;// 11
        v16 = h1 >>> 2;//17

        h2 = v15 | v16; // 55 131
        h1 = h0;// 15 存储 52 的值
        if (flag === 0)
            h0 = v13;// 52
        else if (flag === 1)
            h0 = v_6;
        else if (flag === 2)
            h0 = v_9;
        else if (flag === 3)
            h0 = v_5;
    }
    obj.h0 += h0;
    obj.h1 += h1;
    obj.h2 += h2;
    obj.h3 += h3;
    obj.h4 += h4;
    for (let k in obj) {
        obj[k] <<= 0;
    }
}

function func4(obj) {
    // console.log(obj)
    let arr16 = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"];
    let ans = '', v, v2;
    for (let i = 0; i < 5; i++) {
        v = obj['h' + i];
        for (let j = 28; j >= 0; j -= 4) {
            v2 = v >> j;
            v2 &= 15;
            ans += arr16[v2];
        }
    }
    return ans;
}

function func5(str40) {
    // console.log(str40);
    const obj_16 = {
        "0": 0,
        "1": 1,
        "2": 2,
        "3": 3,
        "4": 4,
        "5": 5,
        "6": 6,
        "7": 7,
        "8": 8,
        "9": 9,
        "A": 10,
        "B": 11,
        "C": 12,
        "D": 13,
        "E": 14,
        "F": 15
    }; //固定值
    const arr_20 = [
        89,
        39,
        179,
        150,
        218,
        82,
        58,
        252,
        177,
        52,
        186,
        123,
        120,
        64,
        242,
        133,
        143,
        161,
        121,
        179
    ]; // 长度为20的数组 固定值
    let new_arr_20 = [], str40_1 = str40.toUpperCase();
    for (let i = 0; i < 20; i++) {
        let key, val, v1, v2;
        key = str40_1[2 * i];
        val = obj_16[key];
        v1 = val * 16;
        key = str40_1[2 * i + 1];
        val = obj_16[key];
        v2 = v1 + val;
        new_arr_20.push(v2 ^ arr_20[i]);
    }
    const arr8 = [16, 1, 32, 12, 19, 27, 8, 5]; // 固定值 长度为8的数组
    const arr8_2 = [23, 14, 6, 36, 16, 40, 7, 19]; // 长度为8的数组 固定值
    let new_arr8 = [], new_arr8_2 = [];
    for (let i = 0; i < 8; i++) {
        new_arr8.push(str40_1[arr8[i]]);
        new_arr8_2.push(str40_1[arr8_2[i]]);
    }
    let str8 = new_arr8.join(''), str7 = new_arr8_2.join('');
    // 利用上面长度为20的数组new_arr_20中的数据生成长度为27的字符串
    // 每3个元素生成4个字符，共计20/3*4=24,最后2个元素生成3个字符，总共27个字符
    // 长度为27的字符串
    const str_65 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
    // 52个字母 + 10个数字 + 3个运算符号 = 65个字符
    let v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, str1 = '';
    for (let i = 0; i < 20; i += 3) {
        v1 = new_arr_20[i];
        v2 = v1 >> 2;
        v3 = v1 & 3;
        v4 = v3 << 4;

        v5 = new_arr_20[i + 1];
        v6 = v5 >> 4;
        v7 = v6 | v4;
        v8 = v5 & 15;
        v9 = v8 << 2; // 189

        if (i + 2 < 20) {
            v10 = new_arr_20[i + 2];
            v11 = v10 >> 6;
            v12 = v9 | v11;
            v13 = v10 & 63;
            str1 += str_65[v2] + str_65[v7] + str_65[v12] + str_65[v13];
        } else {
            str1 += str_65[v2] + str_65[v7] + str_65[v9];
        }
    }
    const str = 'zzc'; // 固定值
    const str2 = /[\/+]/, c = 'g';
    const reg = RegExp.call(undefined, str2, c);
    str1 = str1.replace(reg, "");
    // 使用正则表达式替换字符+ / 为空字符
    // str1最长长度为45 ,经过上述替换操作之后，可能长度不是45，因此sign的值长度是不固定的
    return (str + str7 + str1 + str8).toLowerCase();
}

function main(obj) {
    const arr = func(JSON.stringify(obj));
    const obj2 = func2(arr);
    const str40 = func4(obj2); // 长度为40的字符串
    return func5(str40);
}

const obj = {
    "comm": {
        "cv": 4747474,
        "ct": 24,
        "format": "json",
        "inCharset": "utf-8",
        "outCharset": "utf-8",
        "notice": 0,
        "platform": "yqq.json",
        "needNewCode": 1,
        "uin": "涉及隐私，不便于展示，如果使用的是QQ登录，那么就是你的QQ号，其他的就不知道了，没有具体实操过",
        "g_tk_new_20200303": 664737234,
        "g_tk": 664737234
    },
    "req_1": {
        "method": "DoSearchForQQMusicDesktop",
        "module": "music.search.SearchCgiService",
        "param": {
            "remoteplace": "txt.yqq.song",
            "searchid": "66025209462474659",
            "search_type": 0,
            "query": "我的梦",
            "page_num": 1,
            "num_per_page": 10
        }
    }
};
console.log(main(obj));
// zzc1e67bc8pmsmw9bujxgi607ucutdscsabebc8bbf